package com.simplesoftwares.client.library;
import java.util.Date;

import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.LongBox;
import com.google.gwt.user.client.ui.SuggestBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.simplesoftwares.client.library.composite.CompositeInterface;
import com.simplesoftwares.client.library.mywidgets.MyLongBox;
import com.simplesoftwares.client.library.mywidgets.ObjectListBox;

public class FlexForm extends FlexTable implements FocusHandler
{
	private FormField[][] formfields;
	private FormStyle formStyle;
	
	public FlexForm() 
	{
		super();
	}

	public FlexForm(FormField[][] formfields, FormStyle formStyle) 
	{
		super();
		this.formfields = formfields;
		this.formStyle = formStyle;
		if(formStyle==FormStyle.COLUMNFORM)
			this.createColumnStyleForm();
		else if(formStyle==FormStyle.ROWFORM)
			 createRowForm();
		
		else
			createlayout();
	}

	/****************************************************************/
	public void createRowForm()
	{
		Widget widget;
		FlexCellFormatter formater=getFlexCellFormatter();
		int i=0;
		int k=0;
		int columnlength;
		
		for( i=0;i<this.formfields.length;i++)

		{

			columnlength=this.formfields[i].length;
			
			for(int j=0;j<columnlength;j++)

			{
				widget=formfields[i][j].getWidget();
				 
				if(formfields[i][j]!=null)
				{
				   InlineLabel lbl=new InlineLabel(formfields[i][j].getLabel());
				   formfields[i][j].setHeaderLabel(lbl);
				   setWidget(k,j,lbl);
				   widget=formfields[i][j].getWidget();
				

				
				   if(widget!=null)
					   setWidget(k+1,j,widget);
				   boolean mandatory=formfields[i][j].isMandatory();
				   if(mandatory==true)
				   {
					   InlineLabel msglabel=formfields[i][j].getMandatoryMsgWidget();
					   if(msglabel!=null)
					   {
						   setWidget(k+2, j, msglabel);
						   msglabel.setVisible(false);
					   }
				   }
						   
				   if(formfields[i][j].getWidgetType()==FieldType.Grouping)
				   {
					   RowFormatter format=this.getRowFormatter();
					   format.addStyleName(k,"grouping");
				   }
				}
			 }
			 k=k+3;
		}
		
		k=0;
		for( i=0;i<this.formfields.length;i++)
		{
			columnlength=this.formfields[i].length;
			for(int j=0;j<columnlength;j++)
			{
				if(formfields[i][j]!=null)
				{
					int rowspan=formfields[i][j].getRowspan();
					int colspan=formfields[i][j].getColspan();
					
					formater.setRowSpan(k+1, j, rowspan);
					formater.setColSpan(k+1, j,colspan);
				    formater.setColSpan(k, j,colspan);
				}
			}
			k=k+3;
		}
		
		applyFocusHandler();
	}
	
	/**************************************************************************/
	private void createColumnStyleForm()
	{
		FlexCellFormatter formater=getFlexCellFormatter();
		int k=0;
		int colCount = formfields[0].length;
		int rowCount = formfields.length;
		for(int i=0;i<colCount;i++)
		{
			
			for(int j=0;j<rowCount;j++)
			{
				
				
				if(i<formfields[j].length&&formfields[j][i]!=null)
				{
					
				InlineLabel lbl=new InlineLabel(formfields[j][i].getLabel());
				setWidget(j, k, lbl);
				Widget widg=formfields[j][i].getWidget();
				setWidget(j, k+1, widg);
				
				
				}
			}
			k=k+2;
			
			
		}
		k=0;
		for(int i=0;i<colCount;i++)
		{
			
			for(int j=0;j<rowCount;j++)
			{
				
			
				if(i<formfields[j].length&&formfields[j][i]!=null)
				{
					
				  int rowSpan= formfields[j][i].getRowspan();
				  int colSpan =formfields[j][i].getColspan();
				  
				 // setting rowspan to label
				  formater.setRowSpan(j, k, rowSpan);
				  
				  
				// setting rowspan  colspan to widgets
				  formater.setRowSpan(j, k+1, rowSpan);
				  formater.setColSpan(j, k+1, colSpan);
				 
				  
				 
				}
			}
			k=k+2;
			
		}
		
		
	
		
	}
	
	
	public void createlayout()
	{
		Widget widgets;
		FlexCellFormatter formater=getFlexCellFormatter();
		int i=0;
		
		int columnlength;
		for( i=0;i<this.formfields.length;i++)
		{
			
			columnlength=this.formfields[i].length;
			for(int j=0;j<columnlength;j++)
			{
				if(formfields[i][j]!=null)
				{
				
				InlineLabel lbl=new InlineLabel(formfields[i][j].getLabel());
				setWidget(i,j,lbl);
				widgets=formfields[i][j].getWidget();
				setWidget(i,j,widgets);
				
				
				widgets.setHeight("90%");
				widgets.setWidth("90%");
				}
				
			
		}
			
		
	}
		
	
		for( i=0;i<this.formfields.length;i++)
		{
			 columnlength=this.formfields[i].length;
			for(int j=0;j<columnlength;j++)
			{
				if(formfields[i][j]!=null)
				{
				int rowspan=formfields[i][j].getRowspan();
				int colspan=formfields[i][j].getColspan();
				formater.setRowSpan(i, j, rowspan);
				formater.setColSpan(i, j,colspan);
				}
			}
			
		}
	}
	
	public void clear()
	{
		int noRow = getRowCount();
		for(int k=0;k<noRow;k++)
		{
			int colCount = this.getCellCount(k);
			for(int j=0;j<colCount;j++)
			{
				
					
				Widget widg= this.getWidget(k,j);
				if(widg!=null)
				{
					widg.getElement().getStyle().clearBackgroundColor();
				}
				
				if(widg instanceof TextBox)
				{
					TextBox vb=(TextBox) widg;
					vb.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof IntegerBox)
				{
					IntegerBox ib=(IntegerBox) widg;
					ib.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof CheckBox)
				{
					CheckBox vb=(CheckBox) widg;
					vb.setValue(true);
					resetBorderColor(widg);
				}
				if(widg instanceof TextArea)
				{
					TextArea vb=(TextArea) widg;
					vb.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof LongBox)
				{
					LongBox vb=(LongBox) widg;
					vb.setText("");
					resetBorderColor(widg);
				}
				if(widg instanceof MyLongBox)
				{
					MyLongBox vb=(MyLongBox) widg;
					vb.setText("");
					resetBorderColor(widg);
				}
				if(widg instanceof DateBox)
				{
					DateBox vb=(DateBox) widg;
					vb.getTextBox().setText("");
					resetBorderColor(vb.getTextBox());
				}
				
				if(widg instanceof ListBox)
				{
					ListBox vb=(ListBox) widg;
					vb.setSelectedIndex(0);
					resetBorderColor(widg);
				}
				if(widg instanceof SuggestBox)
				{
					SuggestBox vb=(SuggestBox) widg;
					vb.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof MyLongBox)
				{
					MyLongBox mb=(MyLongBox) widg;
					mb.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof DoubleBox)
				{
					DoubleBox mb=(DoubleBox) widg;
					mb.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof IntegerBox)
				{
					IntegerBox mb=(IntegerBox) widg;
					mb.setText("");
					resetBorderColor(widg);
				}
				
				if(widg instanceof CompositeInterface)
				{
					CompositeInterface a= (CompositeInterface) widg;
					a.clear();
					resetBorderColor((Widget) a);
				}
			}
		}
		
		int rowCount=this.formfields.length;
		for(int x=0;x<rowCount;x++)
		{
			int temp=formfields[x].length;
			for(int j=0;j<temp;j++)
			{
				FormField tempFormField=formfields[x][j];
				
				
				if(tempFormField!=null)
				{
					if(tempFormField.getMandatoryMsgWidget()!=null)
					{
						
						tempFormField.getMandatoryMsgWidget().setVisible(false);
						if(tempFormField!=null&&tempFormField.getWidget()!=null)
						   resetBorderColor(tempFormField.getWidget());
					}
				}
			}
		
		}
		
	}
	
	public boolean validate()
	{
		
		
		boolean result=true;
		int row=this.formfields.length;
		
		for(int k=0;k<row;k++)
		{
			int column=formfields[k].length;
			
			for(int i=0;i<column;i++)
			{
				Widget widg=formfields[k][i].getWidget();
				
				if(formfields[k][i].getLabel()!=null&&formfields[k][i].getLabel().contains("Email"))
				{
					TextBox tb=(TextBox) widg;
					String value=tb.getText();
					
					boolean result1=validateEmail(value.trim());

					if(result1==false)
				    {
				    	if(tb.getText().trim().equals("")==false)
				    	{
				    		result=false;
							changeBorderColor(widg,"#dd4b39");
							
							
							
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
							{
								l.setVisible(true);
								formfields[k][i].getMandatoryMsgWidget().setText("Invalid Email Format!");
				    	}}
				     }	
				}
				
				if(widg instanceof CompositeInterface)
				{
					
					CompositeInterface a= (CompositeInterface) widg;
					boolean resultadress=a.validate();
					if(resultadress==false)
						result=resultadress;	
				}
				
				if(formfields[k][i].isMandatory())
				{
					if(widg instanceof TextBox)
					{
						TextBox tb=(TextBox) widg;
						String value=tb.getText();
						
						if(value.equals(""))
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
							
						}
						
						
						
					}
					
					
					if(widg instanceof TextArea)
					{
						TextArea tb=(TextArea) widg;
						String value=tb.getText();
						
						if(value.equals(""))
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
							
						}
						
						
						
					}
					
					else if(widg instanceof ListBox)
					{
						ListBox lb=(ListBox) widg;
					
						int index=lb.getSelectedIndex();
						if(index==0)
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
							
						}
					}
					
					else if(widg instanceof ObjectListBox)
					{
						ListBox lb=(ListBox) widg;
						
						int index=lb.getSelectedIndex();
						if(index==0)
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
							
						}
					}
					
					else if(widg instanceof DateBox)
					{
						DateBox db=(DateBox) widg;
						Date value=db.getValue();
						if(value==null)
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
							
						}
					}
					
					if(widg instanceof DoubleBox)
					{
						DoubleBox db=(DoubleBox) widg;
						String value=db.getText().trim();
						if(value.equals(""))
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
							
						}
					}
					
					if(widg instanceof SuggestBox)
					{
						SuggestBox sb=(SuggestBox) widg;
						String value=sb.getValue();
						
						if(value.equals(""))
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
						}
					}
					
					if(widg instanceof LongBox)
					{
						LongBox sb=(LongBox) widg;
						Long value=sb.getValue();
						if(value==null)
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
						}
					}
				
					if(widg instanceof MyLongBox)
					{
						MyLongBox sb=(MyLongBox) widg;
						
						Long value=sb.getValue();
						if(value==null)
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
						}
					}
					
					
					if(widg instanceof IntegerBox)
					{
						IntegerBox sb=(IntegerBox) widg;
						
						Integer value=sb.getValue();
						if(value==null)
						{
							result=false;
							changeBorderColor(widg,"#dd4b39");
							InlineLabel l=formfields[k][i].getMandatoryMsgWidget();
							if(l!=null)
								l.setVisible(true);
						}
					}
				}
			}
		}
		return result;
	}
	
	public void applyFocusHandler()
	{
		int row=this.formfields.length;
		
		for(int k=0;k<row;k++)
		{
			int column=formfields[k].length;
			
			for(int i=0;i<column;i++)
			{
				//apply FocusHandler on Email whether it is mandatory or not (format validation) 
				Widget widg1=formfields[k][i].getWidget();
				if(widg1 instanceof TextBox)
				{
					if(formfields[k][i].getLabel().contains("Email"))
						((TextBox) widg1).addFocusHandler(this);
				}
				
				//apply FocusHandler on mandatory fields only.
				if(formfields[k][i].isMandatory())
				{
					Widget widget=formfields[k][i].getWidget();
					
					if(widget instanceof TextBox)
					{
						TextBox tb=(TextBox) widget;
						tb.addFocusHandler(this);
					}
					
					if(widget instanceof ListBox)
					{
						ListBox lb=(ListBox) widget;
						lb.addFocusHandler(this);
					}
					

					if(widget instanceof DoubleBox)
					{
						DoubleBox db=(DoubleBox) widget;
						db.addFocusHandler(this);
					}
					//since FocusHandler can't be apply on SuggestBox
					//we put it on it's ValueBox
					if(widget instanceof SuggestBox)
					{
						SuggestBox sb=(SuggestBox) widget;
						sb.getValueBox().addFocusHandler(this);
					}
				
					if(widget instanceof LongBox)
					{
						LongBox lb=(LongBox) widget;
						lb.addFocusHandler(this);
					}
					if(widget instanceof DoubleBox)
					{
						DoubleBox db=(DoubleBox) widget;
						db.addFocusHandler(this);
					}
					
					if(widget instanceof MyLongBox)
					{
						MyLongBox mb=(MyLongBox) widget;
						mb.addFocusHandler(this);
					}
					
					if(widget instanceof DateBox)
					{
						DateBox date=(DateBox) widget;
						date.getTextBox().addFocusHandler(this);
						
					}
					
					if(widget instanceof IntegerBox)
					{
						IntegerBox date=(IntegerBox) widget;
						date.addFocusHandler(this);
						
					}
					
					if(widget instanceof TextArea)
					{
						TextArea textArea=(TextArea) widget;
						textArea.addFocusHandler(this);
					}
				}
			}
		}
	}
	
	public void setEnabled(boolean status)
	{
		int row=this.formfields.length;
		for(int k=0;k<row;k++)
		{
			int column=formfields[k].length;
			for(int i=0;i<column;i++)
			{
				Widget widg=formfields[k][i].getWidget();
				if(widg instanceof TextBox)
				{
					TextBox tb=(TextBox) widg;
					tb.setEnabled(status);
				}
				
				else if(widg instanceof ListBox)
				{
					ListBox lb=(ListBox) widg;
					lb.setEnabled(status);
				}
				
				else if(widg instanceof SuggestBox)
				{
					SuggestBox sb=(SuggestBox) widg;
					sb.setEnabled(status);
				}
			
				else if(widg instanceof LongBox)
				{
					LongBox lb=(LongBox) widg;
					lb.setEnabled(status);
				}
				
				else if(widg instanceof MyLongBox)
				{
					MyLongBox mb=(MyLongBox) widg;
					mb.setEnabled(status);
				}
				
				else if(widg instanceof IntegerBox)
				{
					IntegerBox sb=(IntegerBox) widg;
					sb.setEnabled(status);
				}
				
				else if(widg instanceof DoubleBox)
				{
					DoubleBox sb=(DoubleBox) widg;
					sb.setEnabled(status);
				}
				
				else if(widg instanceof TextArea)
				{
					TextArea sb=(TextArea) widg;
					sb.setEnabled(status);
				}
				
				
				
				else if(widg instanceof CheckBox)
				{
					CheckBox c=(CheckBox) widg;
					c.setEnabled(status);
				}
				
			
				else if(widg instanceof DateBox)
				{
					DateBox comp=(DateBox) widg;
					comp.setEnabled(status);
				}
				
				
				
				
				else if(widg instanceof Button)
				{
					Button comp=(Button) widg;
					comp.setEnabled(status);
				}
				
				else if(widg instanceof CompositeInterface)
				{
					CompositeInterface comp=(CompositeInterface) widg;
					comp.setEnable(status);
				}
				
				
				
			}
		}
	}
	
	
	
	
/*************************************************************/
	public static enum FormStyle{
		ROWFORM,COLUMNFORM,LAYOUT;
	}


     private void resetBorderColor(Widget widg)
     {
    	 widg.getElement().getStyle().clearBorderColor();
    	
     }
     
     private void changeBorderColor(Widget widg,String color)
     {
    	 widg.getElement().getStyle().setBorderColor(color);
     }

	
	public static boolean validateEmail(String email)
	{
		String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
		
		+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
		return email.matches(EMAIL_PATTERN);     
	}
	
	@Override
	public void onFocus(FocusEvent event) 
	{
		int row=this.formfields.length;
		
		for(int k=0;k<row;k++)
		{
			int column=formfields[k].length;
		
			for(int i=0;i<column;i++)
			{
				Widget widget=formfields[k][i].getWidget();
				
				if(event.getSource().equals(widget) && formfields[k][i].isMandatory()==true)
				{

					if(formfields[k][i].getMandatoryMsgWidget()!=null)
						formfields[k][i].getMandatoryMsgWidget().setVisible(false);
					resetBorderColor(widget);
					return;
				}
				
				//SuggestBox does't implement FocusHandler
				else if(widget instanceof SuggestBox)
				{
					SuggestBox sb=(SuggestBox) widget;
					if(event.getSource().equals(sb.getValueBox()))
					{
						resetBorderColor(sb);
						if(formfields[k][i].getMandatoryMsgWidget()!=null)
							formfields[k][i].getMandatoryMsgWidget().setVisible(false);
						return;
					}
				}
				
				else if(widget instanceof DateBox)
				{
					DateBox sb=(DateBox) widget;
					if(event.getSource().equals(sb.getTextBox()))
					{
						resetBorderColor(sb);
						if(formfields[k][i].getMandatoryMsgWidget()!=null)
							formfields[k][i].getMandatoryMsgWidget().setVisible(false);
						return;
					}
				}
			}
		}
	} 
	
	
}
